home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / fdimg / —‹Œêsrc.lzh / ctrl.c < prev    next >
C/C++ Source or Header  |  1993-03-04  |  34KB  |  1,549 lines

  1. #include    "3DDEF.H"
  2. #include    "GLOBAL.H"
  3. #include    "FORWARD.H"
  4. #include    "XCODE.H"
  5.  
  6. void
  7. ctrl_at()
  8. {
  9. }
  10.  
  11. void
  12. ctrl_a()
  13. {
  14.     CX0 = CPX = 0;    /* 行頭へ */
  15.     work_cursor_cpx();
  16. }
  17.  
  18. void
  19. ctrl_b()
  20. {
  21.     if (TBUFFC || TBUFFC_R) {
  22.         xf_ikinari_kakutei();
  23.     }
  24.     ctrl_b0();
  25. }
  26.  
  27. /* バックしたら1を返す */
  28. int
  29. ctrl_b0()
  30. {
  31.     UNIT *up;
  32.     int flag = 1;
  33.  
  34.     if (TBUFFC) {    /* 変換バッファの右端を確定し、バッファを短くする */
  35.         UBYTE w0[VERY_LONG_LINE*4];
  36.         UINT c,l;
  37.  
  38.         c = xf_back_tb();
  39.         if (TBCP) {    /* 生がある */
  40.             xf_disp_insert(&TX,&TY);
  41.         } else {    /* 生が無くなった */
  42.             work_replace_str_echo(TL0,TBP0,TL1,TBP1,TBUFF,0,TY0);
  43.             xf_init_tb();
  44.             etc_color(NORMAL);
  45.             disp_half_flush(TL0,TY0);
  46.         }
  47.         return;
  48.     }
  49.  
  50.     if (!CPX) {    /* 前行へ */
  51.         up = CL->MAE;
  52.         if (up != HEAD) {
  53.             CL = up;
  54.             line_cl_cl();
  55.             if (--CY < 0) {    /* ウインドウ外 */
  56.                     /* CL をウインドウの中心にして書き直す */
  57.                 disp_cl_center();
  58.             }
  59.             work_line_analyze();
  60.              CPX = work_CX0_to_CPX(VERY_LONG_LINE);    /* 行末へ */
  61.         } else {
  62.             /* 何もしない */
  63.             flag = 0;
  64.         }
  65.     } else {
  66.         CPX--;
  67.     }
  68.     work_cursor_cpx();
  69.     CX0 = CX;
  70.     return(flag);
  71. }
  72.  
  73. /* 右側に半角スペースを挿入 */
  74. void
  75. ctrl_c()
  76. {
  77.     work_insert1_right('\x20');
  78.     line_cl_cl();
  79.     work_line_analyze();
  80.     work_cursor_cpx();
  81. }
  82.  
  83. /* 吸い込みデリート */
  84. void
  85. ctrl_d()
  86. {
  87.     UBYTE c;
  88.  
  89.     if (((c = line_cpx_1byte()) == EOS) || (c == CR)) {    /* 改行若しくは右端 */
  90.         if (CL == (TAIL->MAE)) {    /* 何もしない */
  91.             return;
  92.         }
  93.         if (c) {    /* 行の右端ではない */
  94.             work_delete1char();
  95.             line_cl_cl();
  96.             work_line_analyze();
  97.             work_cursor_cpx();
  98.             CX0 = CX;
  99.         } else {    /* 行の右端である */
  100.             /* 次の行の左端を削除 */
  101.             work_delete1char_special();
  102.             line_cl_cl();
  103.             work_line_analyze();
  104.             work_cursor_cpx();
  105.             CX0 = CX;
  106.         }
  107.     } else {
  108.         work_delete1char();
  109.         line_cl_cl();
  110.         work_line_analyze();
  111.         work_cursor_cpx();
  112.         CX0 = CX;
  113.     }
  114.     change_check();
  115.     disp_trim_tail();
  116. /*    disp_half_flush(CL,CY);*/
  117. /*
  118. window0();
  119. printf("(%x)(%x)(%x)(%x)(%x)(%x)(%x)(%x)",
  120. SCREEN[0],SCREEN[1],SCREEN[2],SCREEN[3],SCREEN[4],SCREEN[5],SCREEN[6],SCREEN[7]);
  121. */
  122. }
  123.  
  124. void
  125. ctrl_e()
  126. {
  127.     CPX = work_CX0_to_CPX(VERY_LONG_LINE);    /* 行末へ */
  128.     work_cursor_cpx();
  129.     CX0 = CX;
  130. }
  131.  
  132. void
  133. ctrl_f()
  134. {
  135.     if (TBUFFC) {
  136.         register UINT c,cl;
  137.  
  138.         if (TBUFFC == TBCP) {    /* 右側の確定はない */
  139.                     /* 新しく1文字持ってきて追加する */
  140.             c = line_cpx_code();
  141.             if (xf_append_tb_check(c)) {/* 変換バッファが一杯 */
  142.                 under_print((STR)"変換バッファが一杯です");
  143.                 etc_beep();
  144.                 return;
  145.             }
  146.             if ((c == CR) || (!c)){            /* 行の右端である */
  147.                 if ((c == CR) || (CL->ATO == TAIL)) {
  148.                     etc_beep();
  149.                     return;
  150.                 }
  151.                 ctrl_f0();
  152.                 c = line_cpx_code();
  153.             }
  154.             ctrl_f0();
  155.             TL1 = CL;    /* 変換バッファの終了行 */
  156.             TPX1 = CPX;
  157.             TX1 = CX;
  158.             TY1 = CY;
  159.             TBP1 = ANALYZE[CPX].BPOS;
  160.             xf_append_tb(c);
  161.         } else {        /* 右側の確定がある */
  162.                     /* TBCP を1つ進める */
  163.             xf_forward_tb();
  164.         }
  165.     } else {
  166.         ctrl_f0();
  167.     }
  168. }
  169.  
  170. /* カーソル右 */
  171. void
  172. ctrl_f0()
  173. {
  174.     UBYTE c;
  175.  
  176.     if (((c = line_cpx_1byte()) == EOS) || (c == CR)) {    /* 次行へ */
  177.         if (CL->ATO != TAIL) {
  178.             if ((CY+1) > (CWY1 - CWY0)) {    /* ウインドウ外 */
  179.                 /* 袋を空にし、CL をウインドウの中心-1にして書き直す */
  180.                 line_seigyou();
  181.                 disp_cl_center_1();
  182.             }
  183.             CY++;
  184.             CL = CL->ATO;
  185.             CPX = 0;
  186.             line_cl_cl();
  187.             work_line_analyze();
  188.         } else {
  189.             /* 何もしない */
  190.         }
  191.     } else {
  192.         CPX++;
  193.     }
  194.     work_cursor_cpx();
  195.     CX0 = CX;
  196. /*
  197. SKEYSET(0x1e);
  198. fep_INKEY();
  199. */
  200. }
  201.  
  202. void
  203. ctrl_g()
  204. {
  205.     if (TBUFFC) {
  206.         xf_init_tb();
  207.         etc_color(NORMAL);
  208.         disp_trans_half_flush(TL0,TBP0,TX0,TY0);
  209.     } else {
  210.         etc_beep();
  211.         etc_set_arg(0);
  212.         under_print((STR)"[中断]");
  213.  
  214.         if (MACRO_DEF_FLAG) {    /* マクロ定義中 */
  215.             if (MACRO_COUNT) {
  216.                 MACRO_SEQUENCE[MACRO_COUNT-1] = 0;    /* 自分を消す */
  217.             } else {
  218.                 MACRO_SEQUENCE[0] = 0;
  219.             }
  220.             MACRO_SEQUENCE[MACRO_COUNT] = MACRO_COUNT = MACRO_DEF_FLAG = 0;
  221.         }
  222.     }
  223. }
  224.  
  225. /* BS */
  226. void
  227. ctrl_h()    /* ,,, */
  228. {
  229.     if (TBUFFC || TBUFFC_R) {
  230. /*        xf_cat_r_init(TBUFF,TBUFF_R);*/
  231.         xf_delete_tb();
  232.         if (TBCP || TBUFFC_R) {    /* 生がある */
  233.             xf_disp_insert(&TX,&TY);
  234.         } else {    /* 生が無くなった */
  235.             work_replace_str_echo(TL0,TBP0,TL1,TBP1,TBUFF,0,TY0);
  236.             xf_init_tb();
  237.             etc_color(NORMAL);
  238.             disp_half_flush(TL0,TY0);
  239.         }
  240.         return;
  241.     }
  242.  
  243.     if ((CL != (HEAD->ATO)) || CPX) {    /* テキストの先頭ではない */
  244.         if (CPX) {        /* 行頭ではない */
  245.             ctrl_b();    /* 左に行って */
  246.             ctrl_d();    /* 右側を削除 */
  247.         } else {        /* 行頭である */
  248.             ctrl_b();    /* 前の行の行末へ行く */
  249.             if (line_cpx_code() != CR) {    /* 改行の上でない */
  250.                 ctrl_b();        /* もう一回左へ */
  251.             }
  252.             ctrl_d();    /* 右側を削除 */
  253.         }
  254.         change_check();
  255.     }
  256. }
  257.  
  258. /* TAB */
  259. void
  260. ctrl_i()
  261. {
  262.     register int a;
  263.  
  264.     if (TBUFFC) {
  265.         fep_push_key(0x105);    /* 暫定 */
  266.         return;
  267.     }
  268.  
  269.     if (a = etc_get_arg()) {
  270.         if ((a <= 0) || (a > TAB_LENGTH_LIMIT)) {
  271.             UBYTE w[MAXLINE];
  272.             sprintf((char *) w,"タブの設定は 1 から %d までです",TAB_LENGTH_LIMIT);
  273.             under_print(w);
  274.         } else if (a > CURRENT_JIZUME) {
  275.             UBYTE w[MAXLINE];
  276. sprintf((char *) w,"タブの設定は現在のカラム数(%d)以下でなくてはいけません",CURRENT_JIZUME);
  277.             under_print(w);
  278.         } else     if (etc_set_tab(a)) {        /* TAB を変更した */
  279.             disp_tab_change(a);
  280.             ctrl_l();
  281.         } else {
  282.             under_print((STR)"タブの設定が同じです");
  283.             work_cursor_cpx();
  284.             return;
  285.         }
  286.     } else {
  287.         work_insert1((UBYTE) TAB);
  288.         under_blanc();
  289.     }
  290.     change_check();
  291.     work_cursor_cpx();
  292. }
  293.  
  294. /* インデント付 CR */
  295. void
  296. ctrl_j()
  297. {
  298.     UBYTE lw[VERY_LONG_LINE];
  299.     register int i,n;
  300.     register UINT c;
  301.     extern UBYTE l[VERY_LONG_LINE*4];
  302.  
  303.     xf_ikinari_kakutei();
  304.     n = i = 0;
  305.     while(1) {
  306.         c = line_cl_code(i++);
  307.         if ((c == ' ') || (c == '\t')) {
  308.             lw[n++] = c;
  309.         } else if (c == L' ') {
  310.             lw[n++] = (L' ' >> 8);
  311.             lw[n++] = (L' ' & 0xff);
  312.         } else {
  313.             lw[n] = EOS;
  314.             break;
  315.         }
  316.     }
  317.     if (n) {    /* 何かある */
  318.         line_cl_strncpy(l,i = ANALYZE[CPX].BPOS);    /* ok */
  319.         l[i] = CR;
  320.         l[i+1] = EOS;
  321.         strcat(l,lw);
  322.         line_cl_strcat(l,i);                /* ok */
  323.         work_cl_replace_plus(i+n+1);
  324.     } else {    /* ^M と同じ */
  325.         work_insert1((UBYTE) CR);
  326.     }
  327.     work_cursor_cpx();
  328. }
  329.  
  330. /* カーソルの右側削除 */
  331. /* 正確には、カーソルが改行の上にある時は改行を削除 -> バッファへ */
  332. /*         右に改行がある時は、改行の前までを削除 -> バッファへ */
  333. /*         右に改行がない時は、行末までを削除 -> バッファへ、そして後ろの行からずりずり */
  334. void
  335. ctrl_k()
  336. {
  337.     UBYTE c;
  338.     int i;
  339.  
  340.     if (commander_is_last_cut_buff_type()) {
  341.     } else {    /* でなければ、カットバッファをクリア */
  342.         buff_clear_cut_buff();
  343.     }
  344.  
  345.     c = line_cpx_1byte();
  346.     if ((CL != (TAIL->MAE))
  347.     || ((c != EOS) && (c != CR))) {
  348.         if (c == CR) {        /* CR の上なら吸い込み削除と同じ */
  349.                     /* ただし、バッファへ送り込む点は違う */
  350.             int b1,b2;
  351.             b1 = ANALYZE[CPX].BPOS;
  352.             b2 = ANALYZE[CPX+1].BPOS;
  353.             work_delete_cl_between(b1,b2,1);
  354.         } else {
  355.             i = work_CX0_to_CPX(VERY_LONG_LINE);    /* 行末のカウント */
  356.             work_delete_cl_between(ANALYZE[CPX].BPOS,ANALYZE[i].BPOS,1);
  357.         }
  358.         line_cl_cl();
  359.         change_check();
  360.         work_line_analyze();
  361.         work_cursor_cpx();
  362.         CX0 = CX;
  363.     } else {
  364.         /* 何もしない */
  365.     }
  366. }
  367.  
  368. /* !!! 整行及び再表示 */
  369. void
  370. ctrl_l()
  371. {
  372.     register int i;
  373.     register UNIT *p;
  374.     int x,y;
  375.     UBYTE left[VERY_LONG_LINE];
  376.  
  377.     line_seigyou();
  378.     init_clear_screen();
  379.     for(i=0;i<MAX_WINDOW;i++) {
  380.         if (WDATA[i].WTEXTS >= 0) {
  381.             disp_btm_line(i);
  382. /*            SCREEN[WDATA[i].WY1+1] = NOT;    */    /* -1 */
  383.         }
  384.     }
  385.     if (TBUFFC) {
  386.         for(i=0;i<TY0;i++) {
  387.             if ((p = SCREEN[i]) != NOT) {
  388.                 disp_1line(i,p);
  389.             }
  390.         }
  391.         line_get_body(left,TL0);
  392.         left[TBP0] = EOS;        /* 未変換の対象になってない左部分 */
  393.         etc_bit_convert_and_disp(0,TY0,left);
  394. /*
  395.         window_loc(0,TY0);
  396.         disp_convert_and_disp(left);
  397. */
  398.         xf_disp_insert(&x,&y);
  399.     } else {
  400.         for(i=0;i<YWIDTH-1;i++) {
  401.             if ((p = SCREEN[i]) != NOT) {
  402.                 disp_1line(i,p);
  403.             }
  404.         }
  405.         work_cursor_cpx();
  406.     }
  407. }
  408.  
  409. void
  410. ctrl_m()
  411. {
  412.     if (TBUFFC || TBUFFC_R) {
  413.         xf_ikinari_kakutei();
  414.         return;
  415.     }
  416.     if (sysflag & 0b1000) {    /* 改行モード */
  417.         if (BITSNS(0x0e) & 0b00000001) {    /* SHIFT */
  418.         } else {
  419.             if (CMDMOD) {    /* ED モードである */
  420.                 ed_ctrl_x();
  421.             } else {
  422.                 ctrl_n();
  423.             }
  424.             ctrl_a();
  425.             return;
  426.         }
  427.     }
  428.     work_insert1((UBYTE) CR);
  429.     line_cl_cl();
  430.     work_line_analyze();
  431.     work_cursor_cpx();
  432. }
  433.  
  434. void
  435. ctrl_n()
  436. {
  437.     if (TBUFFC || TBUFFC_R) {
  438.         xf_ikinari_kakutei();
  439.     }
  440.     if (CL->ATO != TAIL) {
  441.         if ((CY+1) > (CWY1 - CWY0)) {    /* ウインドウ外 */
  442.             /* 袋を空にし、CL をウインドウの中心-1にして書き直す */
  443.             line_seigyou();
  444.             disp_cl_center_1();
  445.         }
  446.         CY++;
  447.         CL = CL->ATO;
  448.         line_cl_cl();
  449.         work_line_analyze();
  450.         if (CMDMOD) {
  451.             CPX = work_CX0_to_CPX(CX);
  452.         } else {
  453.             CPX = work_CX0_to_CPX(CX0);
  454.         }
  455.         work_cursor_cpx();
  456.     } else {
  457.         /* 何もしない */
  458.     }
  459. }
  460.  
  461. void
  462. ctrl_o()
  463. {
  464.     work_insert1_right((UBYTE) CR);
  465.     line_cl_cl();
  466.     work_line_analyze();
  467.     work_cursor_cpx();
  468. }
  469.  
  470. void
  471. ctrl_p()
  472. {
  473.     UNIT *up;
  474.  
  475.     if (TBUFFC || TBUFFC_R) {
  476.         xf_ikinari_kakutei();
  477.     }
  478.     up = CL->MAE;
  479.     if (up != HEAD) {
  480.         CL = up;
  481.         line_cl_cl();
  482.         if (--CY < 0) {    /* ウインドウ外 */
  483.             /* CL をウインドウの中心にして書き直す */
  484.             disp_cl_center();
  485.         }
  486.         work_line_analyze();
  487.         if (CMDMOD) {
  488.             CPX = work_CX0_to_CPX(CX);
  489.         } else {
  490.             CPX = work_CX0_to_CPX(CX0);
  491.         }
  492.         work_cursor_cpx();
  493.     } else {
  494.         /* 何もしない */
  495.     }
  496. }
  497.  
  498. void
  499. ctrl_q()
  500. {
  501.     UINT c;
  502.  
  503.     disp_cursor_on();    /* カーソルを出す */
  504.     disp_show_cursor();    /* カーソルのブリンクを強制的にオンにする */
  505.     fep_key_clear();    /* キーバッファのクリア */
  506.     c = fep_inkey();
  507.     if (c < 0x100) {
  508.         work_insert1((UBYTE) c);
  509.     } else if (c >= 0x8000) {
  510.         work_insert2(c);
  511.     }    /* ファンクションキーを排除するため */
  512.     work_cursor_cpx();
  513. }
  514.  
  515. UBYTE search_w1[VERY_LONG_LINE * 40];    /* サーチの為のワークその位置 */
  516. int bp_bp;    /* CL で発見した場合のゲタ */
  517.  
  518. /* 逆方向次検索 */
  519. void
  520. ctrl_r_next()
  521. {
  522.     ctrl_r0(0);
  523. }
  524.  
  525. /* 逆方向検索 */
  526. void
  527. ctrl_r()
  528. {
  529.     ctrl_r0(1);
  530. }
  531.  
  532. /* 逆方向サーチ */
  533. void
  534. ctrl_r0(int ask)
  535. {
  536.     UBYTE w[VERY_LONG_LINE * 4];
  537.     register STR p;
  538.  
  539.     etc_string_esc_cnv(STRING_ESC1,STRING_ESC1_s);
  540.     sprintf((char *) w,"逆方向検索 [%s]<META>",STRING_ESC1_s);
  541.     if (ask && under_input_esc(w,STRING_ESC1) < 0) {    /* 無効であった = ^G */
  542.         under_print((STR)"[中断]");
  543.     } else {    /* 検索する */
  544.         register UINT p0;    /* 1文字目 */
  545.         register STR smash;
  546.         register UBYTE smashc;
  547.         UNIT *up;    /* 検索対象行 */
  548.         UINT bp;    /* 検索対象バイト位置 */
  549.  
  550.  
  551.         strcpy(STRING_ESC1_u,STRING_ESC1);
  552.         etc_jstrup(STRING_ESC1_u);
  553.         if (p0 = etc_jfirst(STRING_ESC1_u)) {
  554.             line_seigyou();    /* 整行する */
  555.             under_print((STR)"[検索中...]");
  556.             bp_bp = bp = ANALYZE[CPX].BPOS;
  557.             if (bp) {
  558.                 up = CL;
  559.                 line_get_body(w,up);
  560.                 etc_jstrup(w);
  561.                 w[bp] = EOS;
  562.                 /* 現在行のカーソル以降を対象から外す */
  563.             } else {
  564.                 if ((up = CL->MAE) == HEAD) {    /* 前がない */
  565.                     /* みつからないわけだ */
  566.                     goto not_found;
  567.                 }
  568.                 line_get_body(w,up);
  569.                 etc_jstrup(up);
  570.             }
  571.             smash = NULL;
  572.             while(1) {
  573.                 UBYTE code;
  574.  
  575.                 if (((code = fep_get_key()) == '['-'@') || (code == 'G'-'@')) {
  576.                     etc_beep();
  577.                     under_print("[中断]");
  578.                     return;
  579.                 }
  580.  
  581.                 if (p = ctrl_r_search1(p0,w)) {    /* p0 を w の中からさがす */
  582.                     /* 候補が見付かった */
  583.                     /* w -> search_w1 にメイン文字列だけが行ってる */
  584.                     /* p がsearch_w1 の中を指している */
  585.                     if (smash) {    /* 検索のため潰してあった */
  586.                         *smash = smashc;    /* 戻す */
  587.                         smash = NULL;
  588.                     }
  589.                     if (ctrl_r_search2(p,up,STRING_ESC1_u)) {
  590.                         int y;
  591.                         UNIT *p2;
  592.                         int b1,b2;
  593.                         /* 見付かった! */
  594.                         /* up の中に始まりがある */
  595.                     /* p - search_w1 を real_byte でトレースするのだ */
  596. /* p1 行の b1 バイト目から、bc バイトをリアルでトレースし、p2, b2 に位置を返す */
  597.                     ctrl_s_trace_real_byte(up,0,(p - search_w1),&p2,&b2);
  598.                         CL = up;
  599.                         line_cl_cl();
  600.                         if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  601.                             disp_cl_center();
  602.                         } else {
  603.                             CY = y;
  604.                         }
  605.                         work_line_analyze();
  606.                         CPX = work_byte_to_CPX(b2);
  607.                         CX0 = CX = ANALYZE[CPX].XPOS;
  608.                         under_blanc();
  609.                         if (CPX && (line_cl_1byte(CPX-1) == CR)) {
  610.                                 /* 左が改行 */
  611.                             if (CL->ATO == TAIL) {
  612.                                 ctrl_b();
  613.                             } else {
  614.                                 ctrl_f();
  615.                             }
  616.                         }
  617.                         work_cursor_cpx();
  618.                         under_print((STR)"検索成功");
  619.                         return;
  620.                     } else {
  621.         /* 2文字目以降のどこかが違うので、p を EOS で潰してから再検索 */
  622.                         int dummy;
  623.                         smashc = *(smash = p);
  624.                         *smash = EOS;
  625.                         strcpy(w,search_w1);
  626.                         if (*w) {
  627.                             /* 残りがあるのでもう一度この行の中で捜す */
  628.                             continue;
  629.                         }
  630.                     }
  631.                 }
  632.                 if ((up = up->MAE) == HEAD) {    /* 尾なら終わり */
  633.                     break;
  634.                 } else {        /* 次のデータへ */
  635.                     line_get_body(w,up);
  636.                     etc_jstrup(w);
  637.                     smash = NULL;
  638.                 }
  639.             }
  640. not_found:
  641.             under_print((STR)"見付かりません");
  642.         } else {    /* 検索文字列はヌルだったりして */
  643.             under_blanc();
  644.         }
  645.     }
  646. }
  647.  
  648. /* p0 を w の中からさがす */
  649. /* 逆方向探査 */
  650. STR
  651. ctrl_r_search1(UINT p0,STR w)
  652. {
  653.     if (jstrrchr(w,p0)) {    /* まずは下調べ */
  654.                 /* 見付かったなら */
  655.         string_to_main_string(search_w1,w);    /* メインの文字列だけにする */
  656.         return((STR)jstrrchr(search_w1,p0));    /* ルビなどを外すため */
  657.     } else {
  658.         return(NULL);
  659.     }
  660. }
  661.  
  662. /* 必要ならば p の後ろに追加した上で比較する */
  663. int
  664. ctrl_r_search2(STR p,UNIT *wp,STR string)
  665. {
  666.     register int l0,l1,flag;
  667.     register UBYTE c;
  668.     UBYTE work0[VERY_LONG_LINE * 4],work1[VERY_LONG_LINE * 4];
  669.  
  670.     l1 = strlen(p);
  671.     l0 = strlen(string);
  672.  
  673.     if ((strlen(p) < l0) && (wp == CL)) {
  674.         return(0);    /* 最初から現在行ならば、追加してはならない */
  675.     }
  676.  
  677.     while(strlen(p) < l0) {
  678.         if (wp == TAIL) {    /* もう追加出来ない */
  679.             return(0);
  680.         }
  681.         wp = wp->ATO;
  682.         line_get_body(work0,wp);
  683.         etc_jstrup(work0);
  684.         if (wp == CL) {            /* 現在行を追加するときは */
  685.             work0[bp_bp] = EOS;    /* カーソル位置までとする */
  686.         }
  687.         string_to_main_string(work1,work0);    /* メインの文字列だけにする */
  688.         strcat(p,work1);    /* 比較の意味が出るまで追加する */
  689.     }
  690.     c = p[l0];
  691.     p[l0] = EOS;
  692.     flag = !strcmp(p,string);
  693.     p[l0] = c;
  694.     p[l1] = EOS;    /* 追加分は取り除く */
  695.     return(flag);
  696. }
  697.  
  698. /* 次サーチ */
  699. void
  700. ctrl_s_next()
  701. {
  702.     ctrl_s0(0);
  703. }
  704.  
  705. /* 順方向サーチ */
  706. void
  707. ctrl_s()
  708. {
  709.     ctrl_s0(1);
  710. }
  711.  
  712. /* 順方向サーチ */
  713. void
  714. ctrl_s0(int ask)
  715. {
  716.     UBYTE w[VERY_LONG_LINE * 4];
  717.     UNIT *p1,*p2;
  718.     int b1,b2;
  719.     int flag;
  720.  
  721.     etc_string_esc_cnv(STRING_ESC1,STRING_ESC1_s);
  722.     sprintf((char *) w,"検索 [%s]<META>",STRING_ESC1_s);
  723.     if (ask && under_input_esc(w,STRING_ESC1) < 0) {    /* 無効であった = ^G */
  724.         under_print((STR)"[中断]");
  725.     } else {    /* 検索する */
  726.         if (*STRING_ESC1) {    /* ちゃんと文字列がある */
  727.             line_seigyou();    /* 整行する */
  728.             under_print((STR)"[検索中...]");
  729.             strcpy(STRING_ESC1_u,STRING_ESC1);
  730.             etc_jstrup(STRING_ESC1_u);
  731.             flag = ctrl_s_get_string(CL,ANALYZE[CPX].BPOS,STRING_ESC1_u,&p1,&b1,&p2,&b2);
  732.             if (flag > 0) {
  733.                 int y;
  734.  
  735.                 CL = p2;
  736.                 line_cl_cl();
  737.                 if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  738.                     disp_cl_center();
  739.                 } else {
  740.                     CY = y;
  741.                 }
  742.                 work_line_analyze();
  743.                 CPX = work_byte_to_CPX(b2);
  744.                 CX0 = CX = ANALYZE[CPX].XPOS;
  745.                 under_blanc();
  746.                 if (CPX && (line_cl_1byte(CPX-1) == CR)) {
  747.                         /* 左が改行 */
  748.                     if (CL->ATO == TAIL) {
  749.                         ctrl_b();
  750.                     } else {
  751.                         ctrl_f();
  752.                     }
  753.                 }
  754.                 work_cursor_cpx();
  755.                 under_print((STR)"検索成功");
  756.             } else if (flag) {
  757.                 under_print((STR)"[中断]");
  758.             } else {
  759.                 under_print((STR)"見付かりません");
  760.             }
  761.         } else {
  762.             under_blanc();
  763.         }
  764.     }
  765. }
  766.  
  767. /* 順方向サーチのサブ */
  768. /* pp の bb から捜して、p1, b1, p2, b2 に値を返す */
  769. /* 見付かったかどうかを返す */
  770. int
  771. ctrl_s_get_string(UNIT *pp,int bb,STR ss,UNIT **p1,int *b1,UNIT **p2,int *b2)
  772. {
  773.     UBYTE w[VERY_LONG_LINE * 4];
  774.     register UNIT *wp;
  775.     register STR p;
  776.     register UINT p0;    /* 1文字目 */
  777.     register int count;    /* 何個目の p0 か */
  778.     UNIT *up;    /* 検索対象行 */
  779.     UINT bp;    /* 検索対象バイト位置 */
  780.     int llen,flag;
  781.  
  782.     p0 = etc_jfirst(ss);
  783.     up = pp;
  784.     wp = pp->ATO;
  785.     line_get_body(w,pp);
  786.     etc_jstrup(w);
  787.     strcpy(w,&w[bp_bp = bp = bb]);    /* 探索開始点以後 */
  788.     count = 0;
  789.     while(1) {
  790.         UBYTE code;
  791.  
  792.         if (((code = fep_get_key()) == '['-'@') || (code == 'G'-'@')) {
  793.             etc_beep();
  794.             return(-1);
  795.         }
  796.  
  797.         if (p = ctrl_s_search1(p0,w)) {    /* p0 を w の中からさがす */
  798.             llen = strlen(w);
  799.             count++;
  800.             /* 候補が見付かった */
  801.             /* w -> search_w1 にメイン文字列だけが行ってる */
  802.             /* p がsearch_w1 の中を指している */
  803.             if (flag = ctrl_s_search2(p,wp,ss)) {
  804.                 int y;
  805.  
  806.                 /* 見付かった。もしくは終わりにぶつかった */
  807.                 if (flag < 0) {
  808.                     return(0);
  809.                 }
  810.                 /* up の中に始まりがある */
  811.                 ctrl_s_search3(up,p0,STRING_ESC1_u,count,b1,p2,b2);
  812.                 *p1 = up;
  813.                 return(1);
  814.             } else {
  815.     /* 2文字目以降のどこかが違うので、p の次から再検索 */
  816.                 int dummy;
  817.  
  818.                 bp = line_touch_next_char_x(p,0,&dummy);
  819. /* ここで wp を更新可能性あり */
  820.                 strcpy(w,&p[bp]);
  821.                 if (*w) {
  822.                 /* 残りがあるのでもう一度この行の中で捜す */
  823.                     if (llen <= bp) {
  824.                         wp = wp->ATO;
  825.                     }
  826.                     continue;
  827.                 }
  828.             }
  829.         }
  830.         if (wp == TAIL) {    /* 尾なら終わり */
  831.             break;
  832.         } else {        /* 次のデータへ */
  833.             line_get_body(w,up = wp);
  834.             etc_jstrup(w);
  835.             count = bp = 0;
  836.             wp = wp->ATO;
  837.         }
  838.     }
  839.     return(0);
  840. }
  841.  
  842. /* p0 を w の中からさがす */
  843. STR
  844. ctrl_s_search1(UINT p0,STR w)
  845. {
  846.     if (jstrchr(w,p0)) {    /* まずは下調べ */
  847.             /* 見付かったなら */
  848.         string_to_main_string(search_w1,w);    /* メインの文字列だけにする */
  849.         return((STR)jstrchr(search_w1,p0));        /* ルビなどを外すため */
  850.     } else {
  851.         return(NULL);
  852.     }
  853. }
  854.  
  855.  
  856. /* p の後ろに追加した上で比較する */
  857. /* 正で発見、零で非発見、負で終端 */
  858. int
  859. ctrl_s_search2(STR p,UNIT *wp,STR string)
  860. {
  861.     register int l0,l1,flag;
  862.     register UBYTE c;
  863.     UBYTE work0[VERY_LONG_LINE * 4],work1[VERY_LONG_LINE * 4];
  864.  
  865.     l1 = strlen(p);
  866.     l0 = strlen(string);
  867.     while(strlen(p) < l0) {
  868.         if (wp == TAIL) {
  869.             return(-1);
  870.         }
  871.         line_get_body(work0,wp);
  872.         etc_jstrup(work0);
  873.         wp = wp->ATO;
  874.         string_to_main_string(work1,work0);    /* メインの文字列だけにする */
  875.         strcat(p,work1);
  876.     }
  877.     c = p[l0];
  878.     p[l0] = EOS;
  879.     flag = !strcmp(p,string);
  880.     p[l0] = c;
  881.     p[l1] = EOS;    /* 追加分は取り除く */
  882.     return(flag);
  883. }
  884.  
  885. /* up から始まるテキストの中から STRING_ESC1_u を捜し(始まりは count 個目の p0) */
  886. /* b1,p2,b2 にその位置を返す */
  887. /* up == CL のときは bp_bp がゲタとなる */
  888. void
  889. ctrl_s_search3(UNIT *up,UINT p0,STR STRING_ESC1_u,int count,int *b1,UNIT **p2,int *b2)
  890. {
  891.     register UINT c;
  892.     UBYTE s[VERY_LONG_LINE * 4];
  893.     register STR tp,begin;
  894.  
  895.     line_get_body(s,up);
  896.     etc_jstrup(s);
  897.     if ((up == CL) && (bp_bp)) {
  898.         tp = s+bp_bp;    /* ゲタがある */
  899.     } else {
  900.         tp = s;
  901.     }
  902.     while(count--) {
  903.         while(1) {
  904.             begin = tp;    /* チェック開始位置を保存 */
  905.             if (c = *tp++) {    /* 終了ではない */
  906.                 if (c == XCODE_UP) {
  907.                     switch(*tp++) {
  908.                     case XCODE_MARK+0:
  909.                     case XCODE_MARK+1:
  910.                     case XCODE_MARK+2:
  911.                     case XCODE_MARK+3:
  912.                     case XCODE_MARK+4:
  913.                     case XCODE_MARK+5:
  914.                     case XCODE_MARK+6:
  915.                     case XCODE_MARK+7:
  916.                     case XCODE_MARK+8:
  917.                     case XCODE_MARK+9:    /* マーク 0x20 - 0x29 */
  918.                     case XCODE_MARK+10:
  919.                     case XCODE_MARK+11:
  920.                     case XCODE_MARK+12:
  921.                     case XCODE_MARK+13:
  922.                     case XCODE_MARK+14:
  923.                     case XCODE_MARK+15:
  924.  
  925.                     case XCODE_SYSMARK+0:    /* システムマーク */
  926.                     case XCODE_SYSMARK+1:
  927.                     case XCODE_SYSMARK+2:
  928.                     case XCODE_SYSMARK+3:
  929.                     case XCODE_SYSMARK+4:
  930.                     case XCODE_SYSMARK+5:
  931.                     case XCODE_SYSMARK+6:
  932.                     case XCODE_SYSMARK+7:
  933.                     case XCODE_SYSMARK+8:
  934.                     case XCODE_SYSMARK+9:
  935.                     case XCODE_SYSMARK+10:
  936.                     case XCODE_SYSMARK+11:
  937.                     case XCODE_SYSMARK+12:
  938.                     case XCODE_SYSMARK+13:
  939.                     case XCODE_SYSMARK+14:
  940.                     case XCODE_SYSMARK+15:
  941.  
  942.                         break;
  943.                     case XCODE_UL:        /* 下線 */
  944.                         break;
  945.  
  946.                     case XCODE_RB10:    /* 予約:1文字真ん中ルビ */
  947.                     case XCODE_RB1:        /* 1文字ルビ */
  948.                     case XCODE_RB1L:    /* 1文字ルビ左(全角用) */
  949.                     case XCODE_RB1R:    /* 1文字ルビ右(全角用) */
  950.                         tp += 2;        /* ルビであるから、2バイト文字 */
  951.                         break;
  952.                     case XCODE_RB2:        /* 2文字ルビ(全角用) */
  953.                         tp += 4;        /* ルビであるから、2バイト文字 */
  954.                     }
  955.                 } else {
  956.                     if (isprkana(c) || (c < 0x20)) {    /* 普通の1バイトコード */
  957.                         if (p0 == c) {
  958.                             break;
  959.                         }
  960.                     } else {        /* 2バイトコード:もしくは拡張 */
  961.                         c = (c << 8) | (*tp++);
  962.                         if (p0 == c) {
  963.                             break;
  964.                         }
  965.                     }
  966.                 }
  967.             }
  968.         }
  969.     }
  970.     /* count 個を読み飛ばした */
  971.     *b1 = begin - s;
  972.     ctrl_s_trace_real_byte(up,*b1,strlen(STRING_ESC1_u),p2,b2);
  973. }
  974.  
  975. /* p1 行の b1 バイト目から、bc バイトをリアルでトレースし、p2, b2 に位置を返す */
  976. void
  977. ctrl_s_trace_real_byte(UNIT *p1,int b1,int bc,UNIT **p2,int *b2)
  978. {
  979.     UBYTE w[VERY_LONG_LINE * 4];
  980.     register STR tp;
  981.     register UINT c;
  982.  
  983.     if (!bc) {
  984.         *p2 = p1;
  985.         *b2 = b1;
  986.         return;
  987.     }
  988.     line_get_body(w,p1);
  989.     tp = w + b1;
  990.     while(1) {
  991.         if (c = *tp++) {    /* 終了ではない */
  992.             if (c == XCODE_UP) {
  993.                 switch(*tp++) {
  994.                 case XCODE_MARK+0:
  995.                 case XCODE_MARK+1:
  996.                 case XCODE_MARK+2:
  997.                 case XCODE_MARK+3:
  998.                 case XCODE_MARK+4:
  999.                 case XCODE_MARK+5:
  1000.                 case XCODE_MARK+6:
  1001.                 case XCODE_MARK+7:
  1002.                 case XCODE_MARK+8:
  1003.                 case XCODE_MARK+9:    /* マーク 0x20 - 0x29 */
  1004.                 case XCODE_MARK+10:
  1005.                 case XCODE_MARK+11:
  1006.                 case XCODE_MARK+12:
  1007.                 case XCODE_MARK+13:
  1008.                 case XCODE_MARK+14:
  1009.                 case XCODE_MARK+15:
  1010.  
  1011.                 case XCODE_SYSMARK+0:    /* システムマーク */
  1012.                 case XCODE_SYSMARK+1:
  1013.                 case XCODE_SYSMARK+2:
  1014.                 case XCODE_SYSMARK+3:
  1015.                 case XCODE_SYSMARK+4:
  1016.                 case XCODE_SYSMARK+5:
  1017.                 case XCODE_SYSMARK+6:
  1018.                 case XCODE_SYSMARK+7:
  1019.                 case XCODE_SYSMARK+8:
  1020.                 case XCODE_SYSMARK+9:
  1021.                 case XCODE_SYSMARK+10:
  1022.                 case XCODE_SYSMARK+11:
  1023.                 case XCODE_SYSMARK+12:
  1024.                 case XCODE_SYSMARK+13:
  1025.                 case XCODE_SYSMARK+14:
  1026.                 case XCODE_SYSMARK+15:
  1027.  
  1028.                     break;
  1029.                 case XCODE_UL:        /* 下線 */
  1030.                     break;
  1031.  
  1032.                 case XCODE_RB10:    /* 予約:1文字真ん中ルビ */
  1033.                 case XCODE_RB1:        /* 1文字ルビ */
  1034.                 case XCODE_RB1L:    /* 1文字ルビ左(全角用) */
  1035.                 case XCODE_RB1R:    /* 1文字ルビ右(全角用) */
  1036.                     tp += 2;        /* ルビであるから、2バイト文字 */
  1037.                     break;
  1038.                 case XCODE_RB2:        /* 2文字ルビ(全角用) */
  1039.                     tp += 4;        /* ルビであるから、2バイト文字 */
  1040.                 }
  1041.             } else {
  1042.                 if (isprkana(c)|| (c < 0x20)) {    /* 普通の1バイトコード */
  1043.                     if (!(--bc)) {
  1044.                         *p2 = p1;
  1045.                         *b2 = tp - w;
  1046.                         return;
  1047.                     }
  1048.                 } else {        /* 2バイトコード */
  1049.                     tp++;
  1050.                     if ((bc -= 2) <= 0) {
  1051.                         *p2 = p1;
  1052.                         *b2 = (tp - w);
  1053.                         return;
  1054.                     }
  1055.                     if (bc < 0) {
  1056.                         error("???4");
  1057.                     }
  1058.                 }
  1059.             }
  1060.         } else {    /* 一行終了 */
  1061.             p1 = p1->ATO;
  1062.             if (p1 == TAIL) {
  1063.                 error("???5");
  1064.             }
  1065.             line_get_body(w,p1);
  1066.             tp = w;
  1067.         }
  1068.     }
  1069. }
  1070.  
  1071. /* ARG = 4, *4 ,*4 */
  1072. void
  1073. ctrl_u()
  1074. {
  1075.     int a;
  1076.     UINT k;
  1077.  
  1078.     etc_set_arg(4);
  1079.     disp_cursor_on();    /* カーソルを出す */
  1080.     disp_show_cursor();    /* カーソルのブリンクを強制的にオンにする */
  1081.     fep_key_clear();    /* キーバッファのクリア */
  1082.  
  1083.     k = fep_under_inkey();
  1084.     while(k == ('U' - '@')) {    /* またしても CTRL-U であった */
  1085.         if (!(a = etc_get_arg())) {
  1086.             a = 1;
  1087.         }
  1088.         etc_set_arg(a *4);
  1089.         k = fep_under_inkey();
  1090.     }
  1091.     fep_push_key(k);    /* 戻す */
  1092. }
  1093.  
  1094. /* ワイプ */
  1095. /* 指定区間を削除してカットバッファへ */
  1096. void
  1097. ctrl_w()
  1098. {
  1099.     UNIT *wp;
  1100.     int bp;
  1101.     int y;
  1102.     int a;
  1103.  
  1104.     if (commander_is_last_cut_buff_type()) {
  1105.     } else {    /* でなければ、カットバッファをクリア */
  1106.         buff_clear_cut_buff();
  1107.     }
  1108.  
  1109.     if ((a = etc_get_arg()) >= MAX_MARK) {
  1110.         under_print((STR)"マーク番号が不適当です");
  1111.         return;
  1112.     }
  1113.  
  1114.     line_seigyou();
  1115.     if (wp = mark_get_mark(a,&bp)) {
  1116.         if ((wp != CL) || (bp != ANALYZE[CPX].BPOS)) {
  1117.             change_check();
  1118.         }
  1119.  
  1120.         work_delete_to_cut_buff(wp,bp,CL,ANALYZE[CPX].BPOS);
  1121.         work_cursor_cpx();
  1122.     } else {
  1123.         UBYTE w[MAXLINE];
  1124.         sprintf((char *) w,"マーク %1d は設定されていません",a);
  1125.         under_print(w);
  1126.     }
  1127. }
  1128.  
  1129. /* yank... */
  1130. void
  1131. ctrl_y()
  1132. {
  1133.     int i,c = 0,len;
  1134.     int bc,ml;
  1135.     UNIT *wp,*cp;
  1136.     UBYTE w0[VERY_LONG_LINE];
  1137.  
  1138.     line_seigyou();
  1139.     line_cl_strncpy(w0,i = ANALYZE[CPX].BPOS);    /* 左側をコピー */
  1140.     w0[i] = EOS;                    /* w0 にカーソルの前までを転送 */
  1141.     if ((wp = CL->MAE) && (wp != HEAD)) {        /* 前の実体がある */
  1142.         UBYTE w00[VERY_LONG_LINE];
  1143.         int w00l;
  1144.  
  1145.         line_get_body(w00,wp);
  1146.         w00l = wp->LENGTH;
  1147.         c = work_make_cut_buff0_list(w00,w0,&CL_DATA[i]);
  1148.         if (w00l -= strlen(w00)) {
  1149.             c += w00l;
  1150.             line_store_and_echo(wp,w00);
  1151.         } else {
  1152.             /* 何もしない */
  1153.         }
  1154.     } else {
  1155.         c = work_make_cut_buff0_list((STR)NULL,w0,&CL_DATA[i]);
  1156.     }
  1157.     /* -1 = 空、さもなくば、CUT_BUFF の総バイト長を返す */
  1158.     if (c < 0) return;
  1159.     change_check();
  1160.     if (!(wp = work_get_from_cut_buff0_list())) {    /* 一行持って来る */
  1161.         /* 何もない */
  1162.         return;
  1163.     }
  1164.     line_get_body(w0,wp);            /* 中身を取り出す */
  1165.     if (wp->ATO == NIL) {            /* 次は無い */
  1166.         line_set_free(wp);        /* ユニットは捨てる */
  1167.         /* cp の行頭に w0 を挿入する */
  1168.         /* up の指す行の行頭に s1+s2 を挿入し、次々に送って行く。最後まで勝負する */
  1169.     /* エコーする */
  1170.         line_store_and_echo(CL,w0);    /* 現在行と取り換える */
  1171.         CL = line_trace_byte(CL,i,c,&bc,&ml);
  1172.  
  1173.     } else {
  1174.         line_store_and_echo(CL,w0);    /* 現在行と取り換える */
  1175.         line_set_free(wp);        /* 最初の行は捨てる */
  1176.         cp = CL->ATO;
  1177.         while(wp = work_get_from_cut_buff0_list(),wp->ATO) {    /* 最後の一つ前まで */
  1178.             line_insert1_mae_echo(wp,cp);
  1179.         }
  1180.         /* 最後の行だ */
  1181.         line_get_body(w0,wp);        /* 中身を取り出す */
  1182.         line_set_free(wp);        /* ユニットは捨てる */
  1183.         /* cp の行頭に w0 を挿入する */
  1184.         /* up の指す行の行頭に s1+s2 を挿入し、次々に送って行く。最後まで勝負する */
  1185.     /* エコーする */
  1186.         line_arrange(cp,w0,(STR)"");
  1187.         CL = line_trace_byte(CL,i,c,&bc,&ml);
  1188.     }
  1189.     if ((CY = window_is_this_line_in_current(CL)) < 0) {
  1190.         disp_cl_center();
  1191.     }
  1192.     line_cl_cl();
  1193.     work_line_analyze();
  1194.     CPX = work_byte_to_CPX(bc);
  1195.     CX0 = CX = ANALYZE[CPX].XPOS;
  1196.     if (CPX && (line_cl_1byte(CPX-1) == CR)) {    /* 左が改行 */
  1197.         if (CL->ATO == TAIL) {
  1198.             ctrl_b();
  1199.         } else {
  1200.             ctrl_f();
  1201.         }
  1202.     }
  1203.     work_cursor_cpx();
  1204. }
  1205.  
  1206. #if 1
  1207.  
  1208. /* next page */
  1209. void
  1210. ctrl_v()
  1211. {
  1212.     ctrl_v1((CWY1-CWY0)-1-CY,1);
  1213. }
  1214.  
  1215. void
  1216. ctrl_v1(int n,int flag)
  1217. {
  1218.     int y;
  1219.  
  1220.     if (CL != TAIL->MAE) {        /* 最後端ではない */
  1221.         CL = line_trace(CL,max(n,1),(INT *) NIL);
  1222.                     /* 現在表示されている下から2行目(かも) */
  1223.         if ((CY = window_is_this_line_in_current(CL)) < 0) {    /* 出た */
  1224.                     /* 画面の書き換えをする */
  1225.             line_seigyou();
  1226.             disp_cl_y(CY = 0);
  1227.         } else {        /* 入っている */
  1228.             if (flag) {
  1229.                 if (CL->ATO != TAIL) {    /* 画面の書き換えをする */
  1230.                     line_seigyou();
  1231.                     disp_cl_y(CY = 0);
  1232.                 }
  1233.             }
  1234.         }
  1235.         line_cl_cl();
  1236.         work_line_analyze();
  1237.         CX0 = CPX = 0;
  1238.         work_cursor_cpx();
  1239.     } else {
  1240.         ctrl_e();
  1241.     }
  1242. }
  1243.  
  1244. /* before page */
  1245. void
  1246. ctrl_z()
  1247. {
  1248.     ctrl_z0(-(CY -1 +(CWY1-CWY0)));
  1249. }
  1250.  
  1251. void
  1252. ctrl_z0(int n)
  1253. {
  1254.     if (CL != HEAD->ATO) {        /* 最先端ではない */
  1255.         CL = line_trace(CL,min(n,-1),(INT *) NIL);
  1256.         if ((CY = window_is_this_line_in_current(CL)) < 0) {    /* 入っているか */
  1257.             line_seigyou();            /* 入ってないなら画面書き換え */
  1258.             disp_cl_y(CY = 0);
  1259.         } else {        /* カーソルの移動だけである */
  1260.             CY = window_is_this_line_in_current(CL);
  1261.         }
  1262.         line_cl_cl();
  1263.         work_line_analyze();
  1264.         CX0 = CPX = 0;
  1265.         work_cursor_cpx();
  1266.     } else {
  1267.         ctrl_a();
  1268.     }
  1269. }
  1270.  
  1271. #else
  1272.  
  1273. /* next page */
  1274. void
  1275. ctrl_v()
  1276. {
  1277.     int y;
  1278.  
  1279.     if (CL != TAIL->MAE) {        /* 最後端ではない */
  1280.         CL = line_trace(CL,(CWY1-CY)+((CWY1-CWY0-1)/2),(INT *) NIL); /* 2行跨り */
  1281.         ctrl_vz_sub();
  1282.     } else {
  1283.         ctrl_e();
  1284.     }
  1285. }
  1286.  
  1287. /* before page */
  1288. void
  1289. ctrl_z()
  1290. {
  1291.     if (CL != HEAD->ATO) {        /* 最先端ではない */
  1292.         CL = line_trace(CL,-(CY)-((CWY1-CWY0-1)/2),(INT *) NIL); /* 2行跨り */
  1293.         ctrl_vz_sub();
  1294.     } else {
  1295.         ctrl_a();
  1296.     }
  1297. }
  1298.  
  1299. void
  1300. ctrl_vz_sub()
  1301. {
  1302.     int y;
  1303.  
  1304.     line_cl_cl();
  1305.     if ((y = window_is_this_line_in_current(CL)) < 0) {    /* 入ってない */
  1306.         line_seigyou();
  1307.         disp_cl_center();
  1308.     } else {
  1309.         CY = y;
  1310.     }
  1311.     work_line_analyze();
  1312.     CX0 = CPX = 0;
  1313.     work_cursor_cpx();
  1314. }
  1315.  
  1316. #endif
  1317.  
  1318. /* 生入力キャンセル */
  1319. void
  1320. ctrl_ubar()
  1321. {
  1322.     if (TBUFFC || TBUFFC_R) {
  1323.         *TBUFF = EOS;
  1324.         TBUFFC = TBCP = 0;
  1325.         work_replace_str_echo(TL0,TBP0,TL1,TBP1,"",0,TY0);
  1326.         xf_init_tb();
  1327.         etc_func_on();            /* 数字選択状態から脱出 */
  1328.         disp_top_flush(TTOPL00);
  1329.         CL = TL00;
  1330.         CPX = TPX00;
  1331.         CX = TX00;
  1332.         CY = TY00;
  1333.         etc_trim_tail();
  1334.         line_cl_cl();
  1335.         work_line_analyze();
  1336.     }
  1337. }
  1338.  
  1339. extern COMMAND_UNIT command_table[MAX_COMMAND_NUMBER];
  1340. extern COMMAND_UNIT command_table0[MAX_COMMAND_NUMBER];        /* ME */
  1341. extern COMMAND_UNIT command_table1[MAX_COMMAND_NUMBER];        /* ED */
  1342. extern COMMAND_UNIT command_table00[MAX_COMMAND_NUMBER];    /* ME */
  1343. extern COMMAND_UNIT command_table10[MAX_COMMAND_NUMBER];    /* ED */
  1344.  
  1345. /* キーバインド初期化 */
  1346. void
  1347. ctrl_shift_help()
  1348. {
  1349.     register int i;
  1350.  
  1351.     if (CMDMOD) {    /* ed である */
  1352.         ctrl_t_ed0();
  1353.         for(i=0;i<MAX_COMMAND_NUMBER;i++) {
  1354.             command_table[i] = command_table10[i];
  1355.         }
  1356.         under_print("キーバインドをオリジナルの ED モードにしました");
  1357.     } else {    /* me である */
  1358.         ctrl_t_me0();
  1359.         for(i=0;i<MAX_COMMAND_NUMBER;i++) {
  1360.             command_table[i] = command_table00[i];
  1361.         }
  1362.         under_print("キーバインドをオリジナルの ME モードにしました");
  1363.     }
  1364.     etc_kb_wash();
  1365. }
  1366.  
  1367. /* 逆方向サーチのサブ */
  1368. /* pp の bb から ss を捜して、p1, b1, p2, b2 に値を返す */
  1369. /* 見付かったかどうかを返す */
  1370. int
  1371. ctrl_r_get_string(UNIT *pp,int bb,STR ss,UNIT **p1,int *b1,UNIT **p2,int *b2)
  1372. {
  1373.     UBYTE w[VERY_LONG_LINE * 4];
  1374.     register STR p;
  1375.  
  1376.     register UINT p0;    /* 1文字目 */
  1377.     register STR smash;
  1378.     register UBYTE smashc;
  1379.     UNIT *up;    /* 検索対象行 */
  1380.     UINT bp;    /* 検索対象バイト位置 */
  1381.  
  1382.     p0 = etc_jfirst(ss);
  1383.     bp = bb;
  1384.     up = pp;
  1385.     if (bp) {
  1386.         line_get_body(w,up);
  1387.         etc_jstrup(w);
  1388.         w[bp] = EOS;
  1389.         /* bb 以降を対象から外す */
  1390.     } else {
  1391.         if ((pp->MAE) == HEAD) {    /* 前がない */
  1392.             /* みつからないわけだ */
  1393.             goto not_found;
  1394.         }
  1395.         line_get_body(w,up);
  1396.         etc_jstrup(w);
  1397.     }
  1398.     smash = NULL;
  1399.     while(1) {
  1400.         UBYTE code;
  1401.  
  1402.         if (((code = fep_get_key()) == '['-'@') || (code == 'G'-'@')) {
  1403.             etc_beep();
  1404.             return(-1);
  1405.         }
  1406.  
  1407.         if (p = ctrl_r_search1(p0,w)) {    /* p0 を w の中からさがす */
  1408.             /* 候補が見付かった */
  1409.             /* w -> search_w1 にメイン文字列だけが行ってる */
  1410.             /* p がsearch_w1 の中を指している */
  1411.             if (smash) {    /* 検索のため潰してあった */
  1412.                 *smash = smashc;    /* 戻す */
  1413.                 smash = NULL;
  1414.             }
  1415.             if (ctrl_r_search2(p,up,STRING_ESC1_u)) {
  1416.                 int y;
  1417.  
  1418.                 /* 見付かった! */
  1419.                 /* up の中に始まりがある */
  1420.                 /* p - search_w1 を real_byte でトレースするのだ */
  1421. /* p1 行の b1 バイト目から、bc バイトをリアルでトレースし、p2, b2 に位置を返す */
  1422.                 ctrl_s_trace_real_byte(up,0,(p - search_w1),p1,b1);
  1423.                 ctrl_s_trace_real_byte(*p1,*b1,strlen(STRING_ESC1_u),p2,b2);
  1424.                 return(1);
  1425.             } else {
  1426.     /* 2文字目以降のどこかが違うので、p を EOS で潰してから再検索 */
  1427.                 int dummy;
  1428.                 smashc = *(smash = p);
  1429.                 *smash = EOS;
  1430.                 strcpy(w,search_w1);
  1431.                 if (*w) {
  1432.                     /* 残りがあるのでもう一度この行の中で捜す */
  1433.                     continue;
  1434.                 }
  1435.             }
  1436.         }
  1437.         if ((up = up->MAE) == HEAD) {    /* 尾なら終わり */
  1438.             break;
  1439.         } else {        /* 次のデータへ */
  1440.             line_get_body(w,up);
  1441.             etc_jstrup(w);
  1442.             smash = NULL;
  1443.         }
  1444.     }
  1445. not_found:
  1446.     return(0);
  1447. }
  1448.  
  1449. /* p1 行の b1 バイト目から、bc バイトをリアルでトレースし、p2, b2 に位置を返す */
  1450. void
  1451. ctrl_r_trace_real_byte(UNIT *p1,int b1,int bc,UNIT **p2,int *b2)
  1452. {
  1453.     UBYTE w[VERY_LONG_LINE * 4];
  1454.     register STR tp;
  1455.     register UINT c;
  1456.  
  1457.     if (!bc) {
  1458.         *p2 = p1;
  1459.         *b2 = b1;
  1460.         return;
  1461.     }
  1462.     line_get_body(w,p1);
  1463.     tp = w + b1;
  1464.     while(1) {
  1465.         if (c = *tp++) {    /* 終了ではない */
  1466.             if (c == XCODE_UP) {
  1467.                 switch(*tp++) {
  1468.                 case XCODE_MARK+0:
  1469.                 case XCODE_MARK+1:
  1470.                 case XCODE_MARK+2:
  1471.                 case XCODE_MARK+3:
  1472.                 case XCODE_MARK+4:
  1473.                 case XCODE_MARK+5:
  1474.                 case XCODE_MARK+6:
  1475.                 case XCODE_MARK+7:
  1476.                 case XCODE_MARK+8:
  1477.                 case XCODE_MARK+9:    /* マーク 0x20 - 0x29 */
  1478.                 case XCODE_MARK+10:
  1479.                 case XCODE_MARK+11:
  1480.                 case XCODE_MARK+12:
  1481.                 case XCODE_MARK+13:
  1482.                 case XCODE_MARK+14:
  1483.                 case XCODE_MARK+15:
  1484.  
  1485.                 case XCODE_SYSMARK+0:    /* システムマーク */
  1486.                 case XCODE_SYSMARK+1:
  1487.                 case XCODE_SYSMARK+2:
  1488.                 case XCODE_SYSMARK+3:
  1489.                 case XCODE_SYSMARK+4:
  1490.                 case XCODE_SYSMARK+5:
  1491.                 case XCODE_SYSMARK+6:
  1492.                 case XCODE_SYSMARK+7:
  1493.                 case XCODE_SYSMARK+8:
  1494.                 case XCODE_SYSMARK+9:
  1495.                 case XCODE_SYSMARK+10:
  1496.                 case XCODE_SYSMARK+11:
  1497.                 case XCODE_SYSMARK+12:
  1498.                 case XCODE_SYSMARK+13:
  1499.                 case XCODE_SYSMARK+14:
  1500.                 case XCODE_SYSMARK+15:
  1501.  
  1502.                     break;
  1503.                 case XCODE_UL:        /* 下線 */
  1504.                     break;
  1505.  
  1506.                 case XCODE_RB10:    /* 予約:1文字真ん中ルビ */
  1507.                 case XCODE_RB1:        /* 1文字ルビ */
  1508.                 case XCODE_RB1L:    /* 1文字ルビ左(全角用) */
  1509.                 case XCODE_RB1R:    /* 1文字ルビ右(全角用) */
  1510.                     tp += 2;        /* ルビであるから、2バイト文字 */
  1511.                     break;
  1512.                 case XCODE_RB2:        /* 2文字ルビ(全角用) */
  1513.                     tp += 4;        /* ルビであるから、2バイト文字 */
  1514.                 }
  1515.             } else {
  1516.                 if (isprkana(c)|| (c < 0x20)) {    /* 普通の1バイトコード */
  1517.                     if (!(--bc)) {
  1518.                         *p2 = p1;
  1519.                         *b2 = tp - w;
  1520.                         return;
  1521.                     }
  1522.                 } else {        /* 2バイトコード */
  1523.                     tp++;
  1524.                     if ((bc -= 2) <= 0) {
  1525.                         *p2 = p1;
  1526.                         *b2 = (tp - w);
  1527.                         return;
  1528.                     }
  1529.                     if (bc < 0) {
  1530.                         error("???6");
  1531.                     }
  1532.                 }
  1533.             }
  1534.         } else {    /* 一行終了 */
  1535.             p1 = p1->ATO;
  1536.             if (p1 == TAIL) {
  1537.                 error("???7");
  1538.             }
  1539.             line_get_body(w,p1);
  1540.             tp = w;
  1541.         }
  1542.     }
  1543. }
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.